package com.example.xmldemo;

import android.os.Environment;
import android.util.Xml;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class XMLParsingMethods {

    /**【SAX解析XML文件】**/
    public static List<Person> readXmlBySAX(InputStream inputStream) {
        try {
            /**【创建解析器】**/
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser saxParser = spf.newSAXParser();
            XMLContentHandler handler = new XMLContentHandler();
            saxParser.parse(inputStream, handler);
            inputStream.close();
            return handler.getPersons();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**【DOM解析XML文件】**/
    public static List<Person> readXmlByDOM(InputStream inputStream){
        List<Person> persons = new ArrayList<>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document dom = builder.parse(inputStream);

            Element root = dom.getDocumentElement();
            /**【查找所有person节点】**/
            NodeList items = root.getElementsByTagName("person");
            for (int i = 0; i < items.getLength(); i++) {
                Person person = new Person();

                /**【得到第一个person的节点】**/
                Element personNode = (Element) items.item(i);

                /**【获取person节点的id属性】**/
                person.setId(new Integer(personNode.getAttribute("id")));

                /**【获取person节点下的所有子节点（标签之间的空白节点和name/age节点）】**/
                NodeList childsNodes = personNode.getChildNodes();

                /**【遍历所有子节点】**/
                for (int j = 0; j < childsNodes.getLength(); j++) {
                    Node node = (Node) childsNodes.item(j);

                    /**【判断是否为元素类型】**/
                    if(node.getNodeType() == Node.ELEMENT_NODE){
                        Element childNode = (Element) node;
                        /**【判断是否是name元素】**/
                        if ("name".equals(childNode.getNodeName())) {
                            /**【获取name元素下的text节点，然后从text节点获取数据】**/
                            person.setName(childNode.getFirstChild().getNodeValue());
                            /**【判断是否是age元素】**/
                        }else if("age".equals(childNode.getNodeName())){
                            /**【获取age元素下的text节点，然后从text节点获取数据】**/
                            person.setAge(new Short(childNode.getFirstChild().getNodeValue()));
                        }
                    }
                }
                persons.add(person);
            }
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return persons;
    }

    /**【Pull解析器解析XML文件】**/
    public static List<Person> readXmlByPull(InputStream inputStream){
        XmlPullParser parser = Xml.newPullParser();
        try {
            parser.setInput(inputStream,"UTF-8");
            int eventType = parser.getEventType();

            Person currenPerson = null;
            List<Person> persons = null;

            while(eventType != XmlPullParser.END_DOCUMENT){
                switch (eventType){
                    case XmlPullParser.START_DOCUMENT:/**【文档开始事件】**/
                        persons = new ArrayList<>();
                        break;
                    case XmlPullParser.START_TAG:/**【元素（即标签）开始事件】**/
                        String name = parser.getName();
                        if(name.equals("person")){
                            currenPerson = new Person();
                            currenPerson.setId(new Integer(parser.getAttributeValue(null,"id")));
                        }else if(currenPerson !=null){
                            if(name.equals("name")){/**【判断标签名（元素名）是否为name】**/
                                currenPerson.setName(parser.nextText());/**【如果后面是text元素，即返回它的值】**/
                            }else if(name.equals("age")){
                                currenPerson.setAge(new Integer(parser.nextText()));
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:/**【元素结束事件】**/
                        if(parser.getName().equalsIgnoreCase("person") && currenPerson != null){
                            persons.add(currenPerson);
                            currenPerson = null;
                        }
                        break;
                }
                eventType = parser.next();
            }
            inputStream.close();
            return persons;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**【使用Pull解析器生成XML文件内容】**/
    public static String WriteXML(List<Person> persons,Writer writer ){
        XmlSerializer serializer = Xml.newSerializer();
        try {
            serializer.setOutput(writer);
            serializer.startDocument("UTF-8",true);

            /**【第一个参数为命名空间，不使用命名空间可以设置为null】**/
            serializer.startTag("","persons");
            /**【XML文件中要生成的内容】**/
            for(Person person : persons){
                serializer.startTag("","person");
                serializer.attribute("", "id", String.valueOf(person.getId()) );

                serializer.startTag("","name");
                serializer.text(person.getName());
                serializer.endTag("","name");

                serializer.startTag("","age");
                serializer.text(String.valueOf(person.getAge()));
                serializer.endTag("","age");

                serializer.endTag("","person");
            }
            serializer.endTag("","persons");
            serializer.endDocument();
            return writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**【生成XML文件代码】**/
    public static void createXmlFile(List<Person> persons){
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            try {
                File sdCard = Environment.getExternalStorageDirectory();
                File xmlFile = new File(sdCard + File.separator + "testFolder/" + "myitcast.xml");
                FileOutputStream outStream =  new FileOutputStream(xmlFile);
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outStream , "UTF-8");
                BufferedWriter writerFile = new BufferedWriter(outputStreamWriter);

                WriteXML(persons,writerFile);
                writerFile.flush();
                writerFile.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}